package com.qinggeng.project.system.service.impl;

import cn.hutool.core.util.IdUtil;
import com.qinggeng.common.enums.WithdrawalTypeEnum;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.CalendarAdjustUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.framework.config.mq.MQSendUtils;
import com.qinggeng.framework.config.mq.dto.MessageAccountWithdrawaltDTO;
import com.qinggeng.framework.config.mq.enums.MQTypeEnum;
import com.qinggeng.project.api.dto.WithdrawaltDTO;
import com.qinggeng.project.system.domain.UserAccount;
import com.qinggeng.project.system.domain.UserAccountRecordWithdrawal;
import com.qinggeng.project.system.domain.vo.AccountInfoVO;
import com.qinggeng.project.system.mapper.UserAccountMapper;
import com.qinggeng.project.system.mapper.UserAccountRecordWithdrawalMapper;
import com.qinggeng.project.system.service.IUserAccountService;
import com.qinggeng.project.system.service.UserAccountRecordWithdrawalService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class UserAccountRecordWithdrawalServiceImpl implements UserAccountRecordWithdrawalService{

    @Resource
    private UserAccountRecordWithdrawalMapper userAccountRecordWithdrawalMapper;

    @Resource
    private IUserAccountService userAccountService;

    @Resource
    private UserAccountMapper userAccountMapper;
    @Resource
    private MQSendUtils mqSendUtils;
    @Resource
    private RedissonClient redissonClient;

    private  static  final  String ZERO_POINT_THREE="0.30";

    private  static  final  String FIVE_THOUSAND="5000.00";

    @Override
    public UserAccountRecordWithdrawal checkUserAccountRecordWithdrawal(UserAccountRecordWithdrawal userAccountRecordWithdrawal) {
        Long userId=userAccountRecordWithdrawal.getUserId();
        if (null ==userId){
            throw  new CustomException("userId 不能为空");
        }

        Integer withdrawalType=userAccountRecordWithdrawal.getWithdrawalType();
        if (null == withdrawalType){
            throw  new CustomException("getWithdrawalType 不能为空");
        }

        Date date=new Date();
        userAccountRecordWithdrawal.setCreateDate(date);
        userAccountRecordWithdrawal.setCreateTime(date);
        userAccountRecordWithdrawal.setUpdateTime(date);
        Instant instant = Instant.now();
        long timeStampMillis = instant.toEpochMilli();
        userAccountRecordWithdrawal.setCreateTimeStamp(timeStampMillis);
        userAccountRecordWithdrawal.setCreateMonth(CalendarAdjustUtils.getMonthToStr());
        userAccountRecordWithdrawal.setCreateYear(CalendarAdjustUtils.getYearToStr());
        userAccountRecordWithdrawalMapper.insertSelective(userAccountRecordWithdrawal);
        return userAccountRecordWithdrawal;
    }


    public UserAccountRecordWithdrawal getUserAccountRecordWithdrawal(Long userId) {
        Example example =new Example(UserAccountRecordWithdrawal.class);
        example.createCriteria()
                .andEqualTo("userId",userId)
                .andEqualTo("status",0)
                .andEqualTo("delFlag",0);
        return getUserAccountRecordWithdrawal(example);
    }

    @Override
    public boolean withdrawal(WithdrawaltDTO withdrawaltDTO) {

        Integer withdrawaltType= withdrawaltDTO.getWithdrawaltType();
        if (null!=withdrawaltType){
            WithdrawalTypeEnum.isValue(withdrawaltType.toString());
        }
        String money=withdrawaltDTO.getMoney();
        if (StringUtils.isEmpty(money)){
            throw  new CustomException("提现金额不正确");
        }
        BigDecimal bigDecimalMoney=new BigDecimal(money);
        if(bigDecimalMoney.signum() <= 0) {
            throw  new CustomException("提现金额不正确");
        }
        if (new BigDecimal(ZERO_POINT_THREE).compareTo(bigDecimalMoney)>=0){
            throw  new CustomException("单笔金额应该大于0.30元");
        }
        if (new BigDecimal(FIVE_THOUSAND).compareTo(bigDecimalMoney)<=0){
            throw  new CustomException("单笔金额应该不小于5000");
        }
        Long userId=withdrawaltDTO.getUserId();
        AccountInfoVO accountInfoVO=userAccountService.getAccountInfoVO(userId);
        if (null ==accountInfoVO ){
            throw  new CustomException("AccountInfoVO is null");
        }
        String change=accountInfoVO.getChange();
        if ( new BigDecimal(change).signum()<=0 ){
            throw  new CustomException("没有零钱,无法体现");
        }
        String lockKey= UserAccountServiceImpl.USER_ACCOUNT+userId;
        RLock lock=redissonClient.getLock(lockKey);
        if (lock.isLocked()){
            throw  new CustomException("已经提交请稍后");
        }
        lock.lock(5, TimeUnit.SECONDS);
        boolean bl=new BigDecimal(change).compareTo(bigDecimalMoney)>=0;
        if (bl){
            UserAccount userAccount=new UserAccount();
            userAccount.setUserId(userId);
            userAccount.setAccount(bigDecimalMoney);
            userAccountMapper.subUserAccountMoney(userAccount);
            MessageAccountWithdrawaltDTO dto=new MessageAccountWithdrawaltDTO();
            dto.setUserId(userId);
            dto.setWithdrawaltType(withdrawaltType);
            dto.setMoney(money);
            dto.setType(MQTypeEnum.WITHDRAWAL_ACCOUNT.getType());
            mqSendUtils.sendAsynMessage(dto);
            return   true;
        }
        throw  new CustomException("提现不足");
    }

    private  UserAccountRecordWithdrawal getUserAccountRecordWithdrawal(Example example){
        return  userAccountRecordWithdrawalMapper.selectOneByExample(example);
    }
}
